package repository

import (
	"errors"
	"fmt"
	"gitee.com/ling1314/origin-utility/db"
	"gitee.com/ling1314/origin-utility/model"
	log "github.com/sirupsen/logrus"
	"gorm.io/gorm"
)

type userRepository struct{}

func (r userRepository) FindListByDeptId(deptId int64, accountLv []int) (li []*model.User, err error) {
	err = db.GetDB().Where("dept_id = ? AND account_lv IN ?", deptId, accountLv).Find(&li).Error
	return
}

func (r userRepository) Insert(u *model.User) (*model.User, error) {
	if _, exist := r.UsernameExist(u.Username); exist {
		return nil, fmt.Errorf("username already exist")
	}
	if u.Extend.Nickname == "" {
		u.Extend.Nickname = u.Username
	}
	if err := db.GetDB().Create(u).Error; err != nil {
		return nil, err
	}
	return u, nil
}

func (r userRepository) UsernameExist(username string) (*model.User, bool) {
	return r.userExist("username", username)
}
func (r userRepository) userExist(k, v string) (*model.User, bool) {
	user := new(model.User)
	if err := db.GetDB().Where(k+"=?", v).First(&user).Error; !errors.Is(err, gorm.ErrRecordNotFound) {
		if errv := db.GetDB().Model(user).Association("Extend").Find(&user.Extend); errv != nil {
			log.Error(err, "查询用户详情数据失败")
		}
		return user, true
	}
	return nil, false
}

func (r userRepository) FindById(userId int64) (*model.User, error) {
	user := new(model.User)
	var err error
	if err = db.GetDB().First(user, userId).Error; errors.Is(err, gorm.ErrRecordNotFound) {
		return nil, fmt.Errorf("user not exist")
	}
	err = db.GetDB().Model(user).Association("Extend").Find(&user.Extend)
	return user, err
}

func (r userRepository) FindUserByAccount(username string) (user *model.User, err error) {
	if err = db.GetDB().Where("username = ?", username).Find(&user).Error; errors.Is(err, gorm.ErrRecordNotFound) {
		return nil, fmt.Errorf("user not exist")
	}
	err = db.GetDB().Model(user).Association("Extend").Find(&user.Extend)
	return
}

func (r userRepository) BatchInsertMapUserRole(userId int64, roleIds []int64) (err error) {
	l := make([]model.MapUserRole, len(roleIds))
	for i, v := range roleIds {
		l[i] = model.MapUserRole{
			UserId: userId,
			RoleId: v,
		}
	}
	err = db.GetDB().CreateInBatches(&l, len(l)).Error
	return
}

func (r userRepository) FindList(username string) (results []*model.User, total int64, err error) {
	err = db.GetDB().Model(&model.User{}).Omit("password").
		Where("username like ? and deleted_at =0 ", "%"+username+"%").Preload("Extend").Find(&results).
		Count(&total).Error
	return
}

func (r userRepository) DeleteById(id int64) (err error) {
	return db.GetDB().Delete(&model.User{}, id).Error
}

func (r userRepository) DeleteByIds(ids []int64) (err error) {
	if len(ids) > 0 {
		return db.GetDB().Where("user_id in ?", ids).Delete(&model.User{}).Error
	}
	return nil
}

func (r userRepository) UpdatePwd(userId int64, pwd string) error {
	return db.GetDB().Model(&model.User{}).Where("user_id = ?", userId).Update("password", pwd).Error
}

func (r userRepository) FindListByDepId(depId int64) (li []*model.User, total int64, err error) {
	err = db.GetDB().Where(" dept_id =? ", depId).Find(&li).Count(&total).Error
	return
}

func (r userRepository) UpdateById(u *model.User) (err error) {
	tx := db.GetDB().Begin()
	err = db.GetDB().Save(&u).Error
	err = db.GetDB().Save(&u.Extend).Error
	tx.Commit()
	return err
}

func (r userRepository) FindUserRoleList(userId int64) (li []model.Role, err error) {
	err = db.GetDB().Raw("select * from sys_role where role_id in ("+
		" select role_id from  sys_map_user_role where user_id = ? )", userId).Scan(&li).Error
	return
}

func (r userRepository) DeleteMapUserForRole(userId int64) (err error) {
	err = db.GetDB().Exec("delete from sys_map_user_role where user_id = ? ", userId).Error
	return
}

func (r userRepository) FindUserDept(userId int64) (t model.Dept, err error) {
	err = db.GetDB().Raw("select * from sys_team where id in ("+
		" select dept_id from sys_user where user_id = ? )", userId).Scan(&t).Error
	return
}

func (r userRepository) FindRoleIds(userId int64) (roleIds []int64, err error) {
	err = db.GetDB().Raw("select role_id from  sys_map_user_role where user_id = ?", userId).Scan(&roleIds).Error
	return
}

// removeCookieCache 删除服务端的 cookie 缓存，该方法被调用时，对应接口的前端触发时应该同步删除 cookie
func (r userRepository) removeCookieCache(userName string) {
	delete(db.CacheForCookie, userName)
}
